package com.linkgie.galaxyframework.persistence.data;

import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Shape;

/**
 * 字段操作；
 * 
 * @param <T> 实体类型；
 * @param <R> 返回类型；
 */
public interface FieldOperator<T, R> {

    /**
     * 字段名；
     * 
     * @return
     */
    String getFieldName();

    /**
     * 等于；
     * <p>
     * 等效于：{@link #is(Object)}
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R eq(Object value);

    /**
     * 等于；
     * <p>
     * 等效于：{@link #eq(Object)}
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R is(Object value);

    /**
     * 不等于；
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R ne(Object value);

    /**
     * 大于；
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R gt(long value);

    /**
     * 小于；
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R lt(long value);

    /**
     * 大于等于；
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R gte(long value);

    /**
     * 小于等于；
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R lte(long value);

    /**
     * 大于；
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R gt(double value);

    /**
     * 小于；
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R lt(double value);

    /**
     * 大于等于；
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R gte(double value);

    /**
     * 小于等于；
     * 
     * @param value
     * @return 返回当前的属性断言对象自身；
     */
    R lte(double value);

    /**
     * 在指定范围内；
     * 
     * @param values
     * @return
     */
    R in(Object... values);

    /**
     * 不在指定范围内；
     *
     * @param values
     * @return
     */
    R nin(Object... values);

    R mod(Number value, Number remainder);

    /**
     * 包含；
     *
     * @param text 要包含的文本；
     * @return 返回当前的属性断言对象自身；
     */
    R contains(String text);

    /**
     * 包含；
     * 
     * @param text            要包含的文本；
     * @param caseInsensitive 是否忽略大小写；true 时，忽略大小写；false 时，区分大小写；
     * @return 返回当前的属性断言对象自身；
     */
    R contains(String text, boolean caseInsensitive);

    /**
     * 正则表达式匹配；
     *
     * @param regex 正则表达式；
     * @return 返回当前的属性断言对象自身；
     */
    R regex(String regex);

    /**
     * 正则表达式匹配；
     *
     * @param regex   正则表达式；
     * @param options 正则表达式选项；
     * @return 返回当前的属性断言对象自身；
     */
    R regex(String regex, RegexOptions... options);

    /**
     * 存在；
     * 
     * @param value true 时，属性必须存在；false 时，属性必须不存在；
     * @return 返回当前的属性断言对象自身；
     */
    R exists(boolean value);

    R size(int size);

    // TODO: 注：在 MongoDB 中实现 not 操作符具有特殊性，暂不实现此操作；
    // Predicate<T> not();

    R maxDistance(double maxDistance);

    R minDistance(double minDistance);

    R near(double x, double y);

    R withinSphere(Circle circle);

    R within(Shape shape);
}
